package sbc.group1.lab1.alt;

import java.awt.Color;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;

import org.mozartspaces.core.MzsCoreException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import sbc.group1.lab1.common.CarBody;
import sbc.group1.lab1.common.Coatable;
import sbc.group1.lab1.common.Coater;
import sbc.group1.lab1.common.Order;
import sun.misc.Signal;
import sun.misc.SignalHandler;

public class CoaterImpl implements Coater, Runnable {

	public static final Logger log = LoggerFactory.getLogger(CoaterImpl.class);

	
	private final CarService cs;
	private final int coaterId;
	
    private volatile boolean running;
    private final Color coatingColor;

	public static void main(String[] args) throws MzsCoreException,
			URISyntaxException, IOException, InterruptedException, NumberFormatException, NotBoundException {
		CoaterImpl coater = new CoaterImpl(Integer.parseInt(args[0]), new Color(
						Integer.parseInt(args[1])));
		final Thread t = new Thread(coater, "coater");
        Signal.handle(new Signal("INT"), 
            new SignalHandler() {
                @Override
                public void handle(Signal sig) {
                    t.interrupt();
                }
            });
        
        if (System.getProperty("benchmark") != null && System.getProperty("benchmark").equals("true")) {
            Signal.handle(new Signal("HUP"), 
                    new SignalHandler() {
                        @Override
                        public void handle(Signal sig) {
                            t.start();
                        }
                    });
            System.in.read();
        }else {
            t.start();
            System.in.read();
            t.interrupt();
            t.join();
        }
	}

	public CoaterImpl(int coaterId,
			Color coatingColor) throws MzsCoreException, MalformedURLException, RemoteException, NotBoundException {
		cs = (CarService) Naming.lookup("rmi://localhost:1099/CarService");
		//cs.init(configFile, spaceURI);
		this.coaterId = coaterId;
		this.coatingColor = coatingColor;

		

	}

	@Override
	public int getId() {
		return coaterId;
	}

	@Override
	public void run() {
		running=true;
        while(running) {
        	boolean hasDone = false;
            synchronized (this) {
                try {
                	 Coatable toCoat = null;
                	 Color c = coatingColor;
                	 
                	for(Order o : cs.ReadOrders()){
                		
                		CoaterJob j = cs.getCoaterJob(o);
                		if(j != null){
                    		toCoat = cs.takeUncoatedCarBody();
                    		if(toCoat != null){
	                    		c = o.getColor();
	                    		toCoat.coat(c, this);
	                    		cs.addCarBody(o,(CarBody)toCoat);
	                    		hasDone=true;
	                    		break;
                    		}
                    		else{
                    			cs.putCoaterJob(j, o);
                    		}
                		}
                	}
                	
                	if(!hasDone){        		
                		toCoat = cs.takeUncoatedCoatableCarsFirst();
                        toCoat.coat(coatingColor, this);
                        cs.addCoatable(toCoat);
                	}
  
                    log.info("Successfully coated!");
                } catch (InterruptedException e) {
                    running=false;
                    
                    return;
                }catch (RemoteException e) {
                	log.error("", e);
                    running=false;
                    return;
                }
            }
        }
		
	}
	
}
